package com.summer.guardedSuspension;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;

/**嵌套同步导致的嵌套监听锁死**/
public class NestedMonitorLockoutExample {

	public static void main(String[] args) {
		final Helper helper = new Helper();
		System.out.println("Before calling guaredMethod");
		Thread t = new Thread(new Runnable() {
			
			public void run() {
				String result;
				result = helper.xGuarededMethod("test");
				System.out.println(result);
			}
		});
		t.start();
		
		final Timer timer = new Timer();
		
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				helper.xStateChanged();
				timer.cancel();
			}
		}, 50,10);
		
	}
	
	private static class Helper{
		private volatile boolean isStateOK = false;
		private final Predicate stateBeOK = new Predicate(){
			public boolean evaluate() {
				return isStateOK;
			}
		};
		
		private final Blocker blocker = new ConditionVarBlocker();
		
		public synchronized String xGuarededMethod(final String message){
			GuardedAction<String> ga = new GuardedAction<String>(stateBeOK) {
				
				public String call() throws Exception {
					return message+"->received.";
				}
			};
			String result = null;
			try{
				result = blocker.callWithGuard(ga);
			}catch(Exception ex){}
			return result;
		}
		
		public synchronized void xStateChanged(){
			try {
				blocker.signalAfter(new Callable<Boolean>() {
					public Boolean call() throws Exception {
						isStateOK = true;
						System.out.println("state OK");
						return Boolean.TRUE;
					}
				});
			} catch (Exception e) {
			}
		}
	}

}
